﻿using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using ZilLion.Core.ConfigManager.Manager;
using ZilLion.Core.Unities.UnitiesMethods;
using ZilLion.TaskManager.Core.Infrastructure;
using ZilLion.TaskManager.Core.TaskRunTime.AppDomain;
using ZilLion.TaskManager.Core.TaskRunTime.Exe;
using ZilLion.TaskManager.Entity.Config;
using ZilLion.TaskManager.Entity.Entity;
using ZilLion.TaskManager.Repository;

namespace ZilLion.TaskManager.Core.Command
{
    /// <summary>
    ///     开启任务命令
    /// </summary>
    public class StartTaskCommand : BaseCommand
    {
        private readonly TaskConfigRespository _taskConfigRespository = new TaskConfigRespository();
        private readonly TaskModuleConfigRespository _taskModuleRespository = new TaskModuleConfigRespository();

        public override void Execute()
        {
            TaskConfig taskConfig = null;
            var response = _taskConfigRespository.GetTaskConfigById(CommandInfo.Taskid);

            if (response != null && response.TaskConfigList != null)
                taskConfig = response.TaskConfigList.FirstOrDefault();


            if (taskConfig == null)
            {
                CustomTaskLogger.Print(Loglevel.Warn, $"{CommandInfo.Taskid}找不到对应CONFIG");
            }

            else
            {
                var taskModuleresponse = _taskModuleRespository.GetTaskModuleConfigById(taskConfig.TaskmoduleId);
                var taskModuleConfig = taskModuleresponse?.TaskModuleList?.FirstOrDefault();


                if (!PreparePackage(taskConfig))
                {
                    CustomTaskLogger.Print(Loglevel.Warn, $"任务{CommandInfo.Taskid}包文件准备失败");
                }
                else
                {
                    if (ZilLionConfigurationManager.GetConfigInstance<TaskManagerCommonConfig>().TaskRuntimeType ==
                        TaskRuntimeType.Appdomain)
                        TaskAppDomainExcuteProvider.GetInstance().StartTask(taskConfig, taskModuleConfig);
                    else
                        TaskExeRuntime.GetInstance().StartTask(taskConfig, taskModuleConfig);
                }
            }
        }

        private bool PreparePackage(TaskConfig config)
        {
            try
            {
                TaskModuleConfigEntity taskModuleConfigEntity = null;

                #region 下载

                var response = _taskModuleRespository.GetTaskModuleConfigById(config.TaskmoduleId);
                if (response?.TaskModuleList?.FirstOrDefault() != null)
                    taskModuleConfigEntity = response.TaskModuleList.FirstOrDefault();
                if (taskModuleConfigEntity == null) return false;
                var packagepath = Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "TaskContainerPackage",
                    $"TaskNode_{ZilLionConfigurationManager.GetConfigInstance<TaskManagerCommonConfig>().ClientNo.Replace("-", string.Empty)}",
                    "PackageCache"); //包下载路劲
                if (!Directory.Exists(packagepath))
                    Directory.CreateDirectory(packagepath);
                var filepath = Path.Combine(packagepath, config.TaskmoduleId + ".taskpackage"); //下载包文件名
                if (!CheckPackageValid(filepath, taskModuleConfigEntity.Taskmodulepackagecrc)) //如果文件无效重新下载
                {
                    CustomTaskLogger.Print(Loglevel.Warn, $"{config.Taskid}包文件有误，重新下载");

                    if (File.Exists(filepath))
                        File.Delete(filepath); //删除
                    _taskConfigRespository.DownLoadPackage(taskModuleConfigEntity.TaskmoduleId, filepath);
                    if (File.Exists(filepath))
                    {
                        var packagedllpath = Path.Combine(FileHelper.GetRootPath(),
                            $"Package_{taskModuleConfigEntity.Taskmodulepackagekey}");
                        CompressHelper.UnZip(filepath, packagedllpath);
                    }
                    CustomTaskLogger.Print(Loglevel.Warn, $"任务{CommandInfo.Taskid}包文件下载成功");
                }
                if (File.Exists(filepath) &&
                    !File.Exists(Path.Combine(FileHelper.GetRootPath(),
                        $"Package_{taskModuleConfigEntity.Taskmodulepackagekey}")))
                {
                    var packagedllpath = Path.Combine(FileHelper.GetRootPath(),
                        $"Package_{taskModuleConfigEntity.Taskmodulepackagekey}");
                    CompressHelper.UnZip(filepath, packagedllpath);
                }
             

                #endregion
            }

            catch (Exception ex)
            {
                CustomTaskLogger.Print(ex, "下载包过程出错!");
                return false;
            }
            return true;
        }

        /// <summary>
        ///     判断包文件是否有效
        /// </summary>
        /// <returns></returns>
        private bool CheckPackageValid(string filepath, string taskmodulepackagecrc = null)
        {
            if (!File.Exists(filepath))
                return false;

            if (taskmodulepackagecrc.IsNotNullOrEmpty())
                using (var stream = File.OpenRead(filepath))
                {
                    var byteArray = stream.ToByteArray();
                    MD5 md5 = new MD5CryptoServiceProvider();
                    var retVal = md5.ComputeHash(byteArray);
                    var sb = new StringBuilder();
                    foreach (var t in retVal)
                        sb.Append(t.ToString("x2"));
                    if (sb.ToString().ToUpper() != taskmodulepackagecrc?.ToUpper())
                        return false;
                }
            return true;
        }
    }
}